CoreCLRで遭遇する楽しいエラーというか滅ぼされたものとかと戦う
概要
思ったよりエラーが秩序立って出るのでコレクションしてみた。
使ってる基本ライブラリはこれ。
対して、実装している対象はこれ。
Disquuun
https://github.com/sassembla/Disquuun
環境
MacとかUbuntu14とかがメイン。だって確認が簡単なんだもん。
サーバで動く.Net Coreは良いぞ。
遭遇したエラーとかを列挙していく。
いまのところ一番凶悪なエラー Could not load file or assembly 'System.Diagnostics.StackTrace
Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'System.Diagnostics.StackTrace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. A device attached to the system is not functioning.
(Exception from HRESULT: 0x8007001F)
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type, ObjectHandleOnStack keepalive)
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName)
at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark)
at System.Type.GetType(String typeName, Boolean throwOnError)
at System.Diagnostics.StackFrameHelper.InitializeSourceInfo(Int32 iSkip, Boolean fNeedFileInfo, Exception exception)
at System.Diagnostics.StackTrace.CaptureStackTrace(Int32 iSkip, Boolean fNeedFileInfo, Thread targetThread, Exception e)
at System.Exception.get_Source()
at System.Exception.InternalPreserveStackTrace()
at ServerInitializer.Init()
at ConsoleApplication.Program.Main(String[] args)
わけがわからないときにでる。内容は、StackTraceの入ってるassemblyが読めない、っていうことを言われて、は?ってなるっていう。
端的に言うとこれをひいた。
Exception stack is bogus when ulimit is hit. #5782
https://github.com/dotnet/coreclr/issues/5782
場所がさっぱりわからないことになる。
あっちなみにこのエラーが出ると、プロセスが落ちる。
StackTraceよもやま話
stacktraceに関しての話はこのへんもあっておもしろい。っていうかStackTraceないんで、自分で実行した関数の名前を把握できない。うおお、、、
https://github.com/dotnet/corefx/issues/1420
System.IO.IOException: Too many open files
地味にすごく困るエラーがこれ。
や、Disqueのクライアントごときがこんなエラーだしてちゃいけないんだけどさ、
OSで指定してあるFileDescriptorの数を超えてTCPとかのコネクションを貼ろう、ってした場合に上記エラーが出る。
このパラメータをコード上からいじる、っていう文法がCoreCLR上にまだないんで、困っている。
例えばPythonとかだったら、
import resource
resource.setrlimit(
resource.RLIMIT_CORE,
(resource.RLIM_INFINITY, resource.RLIM_INFINITY))
みたいな書き方でOSに対してこのプロセスはどんだけのulimitを使うんだよって指定できるんだけど、この辺はCoreCLRだと
https://github.com/dotnet/coreclr/search?utf8=✓&q=ulimit
shellでセットしたりしてる以外は、、コードに特になってないような、、?
このへんはまあ困っていますね。はい。
Delegate.BeginInvoke/EndInvoke is DEAD
BeginInvokeとかEndInvokeは死にました。やったね?
Unsupportedエラー出そうぜ、っていう話が上がって、叶ってるっぽいんだけどちゃんと出ないことがある。再現したいな~~。
https://github.com/dotnet/coreclr/issues/3811
Socketの接続周りがドラマチックになった
Mac上とかでテストしたいな~みたいな時、IPEndPoint を使ってアドレスとかポートを指定しないとSocketをnewするのに失敗する。
どっかCoreCLRのリポジトリ上にもIssueがあった気がする。
Socketの切断周りがドラマチックになった
socket.CloseとかCloseAsyncとかが全部滅びた。
Dispose()使おうな。という感じで、これもどこかにIssueが上がってて全容が書いてあった気がする。
見つけたら書き足す。
実際にDisposeで書き直したところ、処理が軽量なのか問題は出なかった。なんか見逃してる気がしないでもない。
Reflectionにいろいろ足りない
いろいろやってる最中っぽい。
https://github.com/dotnet/corefx/issues/5381
あのメソッドは今
互換に関する情報は、下記が一番参考になる。公式の移植に関する互換性資料。
http://dotnet.github.io/port-to-core/Moq4_ApiPortabilityAnalysis.htm